package com.sky.web.admin;

import cn.hutool.core.io.resource.ClassPathResource;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.sky.result.Result;
import com.sky.service.ReportService;
import com.sky.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

@RestController
@Slf4j
@RequestMapping(value = "/admin/report")
public class ReportController {

    @Autowired
    private ReportService reportService;

    // 营业额统计
    @GetMapping("/turnoverStatistics")
    public Result turnoverStatistics(
            @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,
            @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end) {
        TurnoverReportVO vo = reportService.turnoverStatistics(begin, end);
        return Result.success(vo);
    }

    // 用户统计
    @GetMapping("/userStatistics")
    public Result userStatistics(
            @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,
            @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end) {
        UserReportVO vo = reportService.userStatistics(begin, end);
        return Result.success(vo);
    }

    // 订单统计
    @GetMapping("/ordersStatistics")
    public Result orderStatistics(
            @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,
            @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end) {
        OrderReportVO vo = reportService.orderStatistics(begin, end);
        return Result.success(vo);
    }

    // 销售排行top10
    @GetMapping("/top10")
    public Result top10(
            @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,
            @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end) {

        SalesTop10ReportVO vo = reportService.top10(begin, end);

        return Result.success(vo);
    }

    // 导出Excel报表
    @GetMapping("/export")
    public void exportExcel(HttpServletResponse response) throws IOException {
        //1. 计算近30天日期范围
        LocalDate begin = LocalDate.now().minusDays(30);
        LocalDate end = LocalDate.now().minusDays(1);
        List<LocalDate> dateList = getDateList(begin, end);
        //2. 声明数据变量
        List<BusinessDataVO> list = new ArrayList<>();
        Double turnover = 0.0;//营业额
        Integer validOrderCount = 0;//有效订单数
        Integer newUsers = 0;//新增用户数
        Double orderCompletionRate = 0.0;//订单完成率
        Double unitPrice = 0.0;//平均客单价
        Integer total = 0; //总记录数
        //3. 调用service查询每天数据
        for (LocalDate date : dateList) {
            //3-1 存入list集合
            BusinessDataVO vo = reportService.businessData(date);
            vo.setDate(date);
            list.add(vo);
            //3-2 封装总数据
            turnover+=vo.getTurnover();//营业额
            validOrderCount+=vo.getValidOrderCount();//有效订单数
            newUsers+=vo.getNewUsers();//新增用户数
            orderCompletionRate+=vo.getOrderCompletionRate();//订单完成率
            unitPrice+=vo.getUnitPrice();//平均客单价
            total+=1;// 总记录数
        }
        //3-3 计算数据
        orderCompletionRate=orderCompletionRate/30;
        unitPrice=unitPrice/30;
        //4. 构建BusinessDataVO对象
        BusinessDataVO businessDataVO = BusinessDataVO.builder()
                .newUsers(newUsers)
                .total(total)
                .beginTime(begin)
                .endTime(end)
                .turnover(turnover)
                .validOrderCount(validOrderCount)
                .orderCompletionRate(orderCompletionRate)
                .unitPrice(unitPrice)
                .build();
        //5. excel填充操作
        //5-1 获取模板文件
        File templateFileName = new ClassPathResource("template/运营数据报表模板.xlsx").getFile();

        //5-2 填充
        try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(templateFileName).build()) {
            WriteSheet writeSheet = EasyExcel.writerSheet().build();

            //填充list集合
            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
            excelWriter.fill(list, fillConfig, writeSheet);

            //填充对象
            excelWriter.fill(businessDataVO, writeSheet);
        }
    }

    // 抽取日期范围计算方法
    private List<LocalDate> getDateList(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = new ArrayList<>();
        LocalDate dateIndex = begin; // 循环指针
        while (!dateIndex.isAfter(end)) {
            dateList.add(dateIndex);
            dateIndex = dateIndex.plusDays(1);// 指针加1
        }
        return dateList;
    }
}
